package server

import (
	"fmt"
	"ginx/config"
	"ginx/config/nginx"
	log2 "ginx/log"
	setting2 "ginx/setting"
	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
	"log"
	"net/http"
	"os"
	"strconv"
)

type Master struct {
}

// 根据每个config.Http.ServerList[i]的信息，创建一个对应的server并返回
func createServer(serverInfo config.Server) http.Server {
	port := strconv.Itoa(serverInfo.Listen)
	fmt.Println("port: ", port)
	router := createRouter(serverInfo)
	server := &http.Server{
		Addr:    ":" + port,
		Handler: router(),
	}
	return *server
}

// 根据每个config.Http.ServerList[i]的信息，创建一组对应的location并返回
func createRouter(serverInfo config.Server) func() http.Handler {
	return func() http.Handler {
		e := gin.New()
		e.Use(gin.Recovery())
		for i := 0; i < len(serverInfo.LocationList); i++ {
			e.GET(serverInfo.LocationList[i].LocationName, func(c *gin.Context) {
				c.String(http.StatusOK, "hello ginx!")
			})
		}
		return e
	}
}

func (master Master) Start() {
	// 读取服务配置
	var settingController setting2.Controller
	setting, errSettingInit := settingController.Init("../conf/setting.yml")
	if errSettingInit != nil {
		fmt.Println(errSettingInit)
	}

	// 创建业务日志
	var logger log2.Logger
	fmt.Println(setting.LogMode)
	switch setting.LogMode {
	case "kafka":
		var logger2 *log2.LoggerKafka
		// 还需要new初始化了这个指针之后，才能赋值给指针
		logger2 = new(log2.LoggerKafka)
		logger2.Init(setting.LogKafkaSetting.Host, setting.LogKafkaSetting.Port, setting.LogKafkaSetting.Topic)
		logger = logger2
	case "elasticsearch":
		var logger2 *log2.LoggerElasticsearch
		// 还需要new初始化了这个指针之后，才能赋值给指针
		logger2 = new(log2.LoggerElasticsearch)
		logger2.Init(setting.LogElasticsearchSetting.Host, setting.LogElasticsearchSetting.Port, setting.LogElasticsearchSetting.Index)
		logger = logger2
	case "file":
		var logger2 *log2.LoggerFile
		logger2 = new(log2.LoggerFile)
		logger2.Init(setting.LogFileSetting.Path)
		logger = logger2
	default:
		os.Exit(1)
	}

	logger.Log("123456")
	logger.Log("abcdef")
	logger.Log("你好，世界！")

	// 创建运行日志
	logFile, errCreate := os.Create("error.log")
	if errCreate != nil {
		fmt.Println(errCreate)
		//panic("log error")
		return
	}
	log.SetOutput(logFile)
	log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)

	// 初始化业务配置文件，gin所需参数从config中获取
	// 底层用ReadFile实现，传入的路径不需要相对main.go取../conf/，而只需要基于项目根路径 ginx 取 conf/ 即可
	// var configController yaml.ConfigController
	var configController nginx.ConfigController
	config, errInit := configController.Init("../conf/ginx.conf")
	fmt.Println(config)
	if errInit != nil {
		log.SetPrefix("[Error]")
		log.Println("errInit:", errInit)
	}

	// 创建一组server
	var serverlist []http.Server
	for _, serverInfo := range config.Http.ServerList {
		server := createServer(serverInfo)
		serverlist = append(serverlist, server)
	}
	fmt.Println("len(serverlist): ", len(serverlist))

	// 运行一组server
	var (
		g errgroup.Group
	)

	for _, server := range serverlist {
		// server := server 很重要，不可省略！不然只能监听到最后一个
		server := server
		g.Go(func() error {
			fmt.Println("start a new server")
			errListenAndServer := server.ListenAndServe()
			return errListenAndServer
		})
	}

	if errWait := g.Wait(); errWait != nil {
		log.Fatal(errWait)
	}
}
